from typing import Optional

from fastapi import HTTPException
from tortoise.expressions import When, Case

from src.db import db_models
from src.db.db_models import Papers


# 获取指定试卷
async def get_paper_service(paper_id):
    try:
        return await Papers.filter(is_valid=True).get(id=paper_id)
    except:
        raise HTTPException(status_code=400, detail="未找到该试卷")


# 更新试卷
async def update_paper_services(
        paper_id: int,
        name: Optional[str] = None,
        desc: Optional[str] = None,
        author: Optional[str] = None,
        is_valid: Optional[bool] = None  # 新增valid参数
):
    # 查询试卷
    paper = await Papers.filter(id=paper_id).first()
    if not paper:
        return {"code": 404, "message": "试卷不存在"}

    # 构建更新数据字典
    update_data = {}
    if name is not None:
        update_data["name"] = name
    if desc is not None:
        update_data["desc"] = desc
    if author is not None:
        update_data["author"] = author
    if is_valid is not None:  # 处理valid字段
        update_data["is_valid"] = True

    # 执行更新
    await Papers.filter(id=paper_id).update(**update_data)
    return {"code": 200, "message": "更新成功"}


# 分数分配算法
async def score_allocate(score: int, ques: str):
    score = int(score)
    ques = ques.replace('，', ',').replace("'", '')
    ques_list = [int(i) for i in ques.split(',')]

    low_list = await (db_models.Questions
                      .filter(id__in=ques_list, leixing__in=['选择题', '判断题'])
                      .values('id', 'tigan'))

    mid_list = await (db_models.Questions
                      .filter(id__in=ques_list, leixing='填空题')
                      .values('id', 'tigan'))

    high_list = await (db_models.Questions
                       .filter(id__in=ques_list, leixing='简答题')
                       .annotate(
        sort_order=Case(
            When(nandu__in=['简单', '简单难度'], then='1'),
            When(nandu__in=['一般', '一般难度'], then='2'),
            When(nandu__in=['困难', '困难难度'], then='3'),
            default='0'
        )
    )
                       .order_by('sort_order')
                       .values('id', 'tigan'))

    a = len(low_list) + len(mid_list) * 2 + len(high_list) * 4
    if score < a:
        raise HTTPException(422, '分值设置太低，请重新设置一个合理的分数')
    low_score = score // a
    mid_score = (score * 2) // a
    high_score = (score - low_score * len(low_list) - mid_score * len(mid_list)) // len(high_list) / 2
    extra_score = score - low_score * len(low_list) - mid_score * len(mid_list) - high_score * len(high_list)
    list1 = [{'question_id_id': i['id'], 'score': low_score} for i in low_list]
    list2 = [{'question_id_id': i['id'], 'score': mid_score} for i in mid_list]
    list3 = [{'question_id_id': i['id'], 'score': high_score} for i in high_list]
    list3[-1]['score'] += extra_score
    return list1 + list2 + list3


# paper表和paper_detail表同时插入，更新试卷

async def add_paper(paper_id, name, desc, author, score: int, ques):
    paper = await db_models.Papers.create(id=paper_id,
                                          name=name,
                                          desc=desc,
                                          author=author,
                                          score=score)
    a = await score_allocate(score, ques)
    paper_detail = await db_models.Paper_Detail.bulk_create(
        [db_models.Paper_Detail(paper_id_id=paper_id, question_id_id=data['question_id_id'], score=data['score'])
         for data in a])
    return paper_detail
